package ru.stool.erp.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import ru.stool.erp.grants.EmployeeGrantsCalculator;
import ru.stool.erp.grants.EmployeeGrantsManager;
import ru.stool.erp.model.dao.EmployeeDAO;
import ru.stool.erp.model.dao.factory.AbstractDAOFactory;
import ru.stool.erp.model.entities.EmployeeEntity;

public class UserDetailsServiceImpl implements UserDetailsService {

	@Override
	public UserDetails loadUserByUsername(String userName)
			throws UsernameNotFoundException {
		
		AbstractDAOFactory daoFactory=AbstractDAOFactory.getDAOFactory(AbstractDAOFactory.HIBERNATE_DAO_FACTORY);
		EmployeeDAO empDAO=daoFactory.getEmployeeDAO();
		EmployeeEntity emp=empDAO.findByLogin(userName);
		
		if(emp==null)
			throw new UsernameNotFoundException("User with name="+userName+" not found");
		
		UserDetails user=transformEmployeeEntity(emp);
		
		return user;
	}
	
	protected UserDetails transformEmployeeEntity(EmployeeEntity emp){
		Collection<GrantedAuthority> authorities=transformGrants(emp);
		
		UserDetails user=new User(emp.getLogin(), 
				                  emp.getPassword(),
				                  true,
				                  true,
				                  true,
				                  emp.isActive(),
				                  authorities);
		return user;
	}
	
	protected Collection<GrantedAuthority> transformGrants(EmployeeEntity emp){
		if(emp==null)
			return new ArrayList<GrantedAuthority>();
		
		EmployeeGrantsCalculator calc=EmployeeGrantsManager.getCalculator();
		List<String> grants=calc.calculate(emp);
		
		Collection<GrantedAuthority> ret=new ArrayList<GrantedAuthority>();
		
		for(String grant: grants){
			ret.add(new GrantedAuthorityImpl(grant));
		}
		
		return ret;
	}

}
